恨非凌空鸟,欲飞缺双翅。
Jinja2可以对Html文件进行渲染加工,把你后端服务器的数据以变量的形式传递给静态html页面。常见的用法如下
快速入门
在项目下新建一个templates目录,随便创建一个html文件,名字为6.html。
from flask import render_template,Flask
app = Flask(__name__,template_folder='templates')
# template_folder 指向你的模板目录
你的后端程序中要返回一个变量的数据,这个变量名为data,比如data=666,这个时候想要在html中显示这个data的数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
{{data}}
</body>
</html>
这样页面就会输出666了,当然首先你要先安装jinja2模块,这个在你安装flask的时候就一起安装了,flask中模板渲染使用render_template。
@app.route('/login')
def log():
data = 666
return render_template('6.html',data=data)
# dataaaa = data也可以这么写,但是在6.html中的花括号内就要改写成dataaaa
传递参数
传递字典
@app.route('/login')
def log():
data1 = {
'name':'langzi',
'age':'20'
}
data2 = {
'name':'zhaohan',
'age':'20'
}
return render_template('6.html',d1=data1,d2=data2)
在静态文件中这么获取字典的值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
{{d1.name}}
{{d1['name']}}
</body>
</html>
传递列表
@app.route('/login')
def log():
data = [1,2,3,4,5,6,7,8]
return render_template('6.html',dd=data)
静态文件中可以迭代列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
{% for x in dd %}
{{x}}
{% endfor %}
</body>
</html>
每次迭代的时候都可以插入html的代码,比如换行或者加上a标签等等
迭代字典
{% for key, value in dd.iteritems() %}
{{ key }}
{{ value }}
{% endfor %}
设置变量
在静态文件中加入name的变量
{% set name='xx' %}
控制语句
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
{% if 1>5 %}
hahaha
{% else %}
liuliuliu
{% endif %}
</body>
</html>
运算符
+号运算符:可以完成数字相加,字符串相加,列表相加。但是并不推荐使用+运算符来操作字符串,字符串相加应该使用~运算符。
-号运算符:只能针对两个数字相减。
/号运算符:对两个数进行相除。
%号运算符:取余运算。
*号运算符:乘号运算符,并且可以对字符进行相乘。
**号运算符:次幂运算符,比如2**3=8。
in操作符:跟python中的in一样使用,比如{{1 in [1,2,3]}}返回true。
~号运算符:拼接多个字符串,比如{{"Hello" ~ "World"}}将返回HelloWorld。
模板继承
Jinja2是可以通过继承别的模板来引用的,比如像什么头部标签,编码格式等等都可以放在一个模板里,然后别的模板直接继承该模板即可。
在templates目录下创建一个名为layout.html文件。然后在别的模板引入layout.html模板,使用的引入的单词是extends。
layout.html的内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>引入的模板</title>
</head>
<body>
{% block head %}
这是头部的信息
{% endblock %}
{% block content %}
这种中间内容
{% endblock %}
{% block foot %}
这是底部的信息
{% endblock %}
</body>
</html>
然后之前的404.html的页面中就可以不需要什么头部标签等等重复的代码,可以直接从layout.html中直接引入即可。
404.html 内容如下
{% extends layout.html %}
{% block content %}
看什么看啊,小帅哥
{% endblock %}
如果这个时候打开404.html会显示
这是头部的信息
看什么看啊,小帅哥
这是底部的信息
这就是直接继承和替换了,同理。如果不想替换的话,加上一行super(),就不会把中间的内容替换
{% extends "layout.html" %}
{% block content %}
{{ super() }}
看什么看啊,小帅哥
{% endblock %}
这样就会显示出完整的内容
这是头部的信息
这种中间内容
看什么看啊,小帅哥
这是底部的信息
管道命令
就像Linux一样,使用|在命令行之间传递数据
过滤器
default(),默认值。如果前面传递过来的值为False的话,就显示出default()的内容
{{data.sxxxxx | default('没有数据')}}
因为data.sxxxxx这个变量不存在,所以为False,这样就会先显示没有数据。
统计长度
{{data | length()}}
消息闪现
首先要导入这个库,这个库涉及到session(),所以需要配置flask的SECRET_KEY。SECRET_KEY写在config.py配置文件中,值是任意不重复的字符串SECRET_KEY=’asd156asa32f1s3a2s1x23a5sd4a63w54d13a’
from flask import flash,render_template
然后在视图函数中使用这个库
@app.route('/login/')
def login():
data = {
name:'admin'
}
flash('langzi 66')
return render_template('test.html',data=data)
在模板test.html中
{%set msg=get_flashed_messages()%}
{{msg}}
{{data.name}}
这样页面就会显示
['langzi 666']
admin
在函数中return只能用一次,但是flash()可以运行很多次。并且他有自己的作用域,他的数据类型是数组,可以用for循环。
模版页面中引入静态文件
静态文件主要包括有CSS样式文件、JavaScript脚本文件、图片文件、字体文件等静态资源。
在Jinja中加载静态文件只需要通过url_for全局函数就可以实现:
<link href="{{ url_for('static',filename='about.css') }}">
引入static目录下的about.css文件。
url_for函数用法
url_for的本质是根据函数名反向生成url,使用函数 url_for() 来针对一个特定的函数构建一个 URL。它能够接受函数名作为第一参数,以及一些关键字参数, 每一个关键字参数对应于 URL 规则的变量部分。未知变量部分被插入到 URL 中作为查询参数。
url_for()可以使用程序 URL 映射中保存的信息生成 URL,url_for操作对象是函数,而不是route里的路径。url_for() 函数最简单的用法是以视图函数名作为参数, 返回对应的 URL。例如,在示例程序中 hello.py 中调用 url_for(‘index’) 得到的结果是 /。
redirect 是重定向函数,输入一个URL后,自动跳转到另一个URL所在的地址,例如,你在函数中写 return redirect(‘xxxxxx’) 页面就会跳转向xxxxx页面。
from flask import Flask,redirect,url_for
app = Flask(__name__)
@app.route('/')
def index():
login_url = url_for('login')
return redirect(login_url)
return u'这是首页'
@app.route('/login/')
def login():
return u'这是登陆页面'
@app.route('/question/<is_login>/')
def question(is_login):
if is_login == '1':
return u'这是发布问答的页面'
else:
return redirect(url_for('login'))
if __name__ == '__main__':
app.run(debug=True)
在模板中使用url_for,实现在页面点击文字,跳转至另一个页面。其实很简单:
1.首先通过视图函数,渲染出一个页面
@app.route('/')
def index():
return render_template('index.html')
2.在index.html这个文件中,添加
<p><a href="{{ url_for('login') }}">登录</a></p>
3.这样,点击 登录 字样,通过login()对应的url跳转到另一个页面了(前提是这个页面存在)
其实就是对应你在视图函数中定义的函数名,而不是路由中的路径,别忘了加上单引号。还可以传递参数:
url_for() 函数最简单的用法是以视图函数名(或者app.add_url_route() 定义路由时使用
的端点名)作为参数,返回对应的URL。例如,在当前版本的hello.py 程序中调用url_
for('index') 得到的结果是/。调用url_for('index', _external=True) 返回的则是绝对地
址,在这个示例中是http://localhost:5000/。
使用url_for() 生成动态地址时, 将动态部分作为关键字参数传入。例如,url_for
('user', name='john', _external=True) 的返回结果是http://localhost:5000/user/john。
传入url_for() 的关键字参数不仅限于动态路由中的参数。函数能将任何额外参数添加到
查询字符串中。例如,url_for('index', page=2) 的返回结果是/?page=2。
url_for不仅仅用来导入静态文件,还可以放在表单提交中。
<form action="{{url_for(web.search)}}" method="get">
这里的web.search是web目录下创建的蓝图。
传递数据
关于HTML的基础语法,name与value的方法。html中form表单才有action属性。
<form action='web.search' method='POST'>
<button type='submit' name='name' value={{x}}>
</form>
其中x是获取的数据,直接传递给另一个视图函数来处理。
如果是要用href方法来传递数据
<a href="{{url_for('web.search',idx='萝莉')}}" class="list-group-item">萝莉</a>
其中serach的视图函数如下
@web.route('/search/',methods=['POST','GET'])
def search():
if request.method == 'POST':
idx = request.form['idx']
data=meizi(idx)
print data
if data == [] or data == None:
return render_template('404.html')
else:
return render_template('result.html', data=data)
else:
idx = request.args.get('idx')
data = meizi(idx)
if data == [] or data == None:
return render_template('404.html')
else:
return render_template('result.html', data=data)
静态文件夹的设计
静态文件夹:tamplates,负责被渲染的html,关于他的路径设置,如果你放在根目录下的话,就属于应用级别层,在生成实例化app对象的时候使用相对的路径即可。
app = Flask(__name__,template_folder='templates')
如果你需要不同功能下的静态文件都不一样的话,可以放在不同功能的文件夹下,比如我的web目录下有个templates的静态文件夹,生成的时候就要加上web目录
app = Flask(__name__,template_folder='web/templates')
一般来说都是放在主目录下,方便共享图片信息等。
在测试的时候发现直接访问静态文件反馈404,后来尝试在启动自定指定静态文件路径即可解决
app = Flask(__name__,template_folder=('web/templates'),static_folder=('web/static'))